﻿#region GNU General Public License
/*
-----------------------------------------------------------------------------
This source file is part of jscc
    (Javascript with Classes)
For the latest info, see http://code.google.com/p/jscc

Copyright (c) 2011 Tapani Valkonen

jscc is free software: you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the 
Free Software Foundation, either version 3 of the License, or (at your option)
any later version. 
 
jscc is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
for more details.

You should have received a copy of the GNU General Public License 
along with jscc. If not, see http://www.gnu.org/licenses/.
-----------------------------------------------------------------------------
*/
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using jscc.CodeGen;

namespace jscc.Ast
{
    public enum Accesability
    {
        Public,
        Private,
        Static
    }

    /*public enum ModifierFlags
    {
        None,
        Abstract = 1 << 0,
        Extern = 1 << 1,
        //INLINE = 1 << 2,
        //NEW = 1 << 3,
        Override = 1 << 2,
        Static = 1 << 3,
        Virtual = 1 << 4,
    }

    public enum VariableType
    {
        None,
        Object,
        Int,
        //Uint,
        Float,
        Double,
        //Char,
        String,
        Void,
        Uknown,
    }*/

    public abstract class AstNodeVisitor
    {
        public abstract void Visit(AstNode node);
        public virtual void Leave(AstNode node) {}

        private int level = 0;
        public int Level
        {
            get { return level; }
            set { level = value; }
        }
    }

    public class AstNode
    {
        List<AstNode> children;

        public AstNode(string name)
        {
            this.name = name;

            Construct();
        }

        private void Construct()
        {
            children = new List<AstNode>();
        }

        public AstNode AddChildren(AstNode node)
        {
            children.Add(node);
            node.Parent = this;
            return node;
        }

        public void MakeLastChildren(AstNode node)
        {
            AstNode found = null;

            foreach (AstNode child in children)
            {
                if (child == node) found = child;
            }

            if (found == null) return;

            children.Remove(found);
            AddChildren(found);
        }
        
        public void Accept(AstNodeVisitor visitor)
        {
            visitor.Visit(this);

            visitor.Level++;

            foreach (AstNode child in children)
            {
                child.Accept(visitor);
            }

            visitor.Leave(this);

            visitor.Level--;
        }

        protected string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        // TODO: set should be private
        public AstNode Parent { get; set; }

        public CodeNode Writer { get; protected set; }
    }
}
